package cn.doyens.reggie.controller;

import cn.doyens.reggie.common.R;
import cn.doyens.reggie.entity.User;
import cn.doyens.reggie.service.UserService;
import cn.doyens.reggie.util.SMSUtils;
import cn.doyens.reggie.util.ValidateCodeUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
      private RedisTemplate redisTemplate;
    @Autowired
    private UserService userService;


    /**
     *    分析:
     *        1.通过工具类获取 长度为4位的 随机验证码 code
     *        2.取出user中的phone字段
     *        3.通过阿里云SMS服务 为指定手机号码发送短信验证码
     *        4.将生成的验证码code 保存到session域中
     *        5. 通过return返回 R对象 提示短信发送成功
     *
     * @param user
     * @param request
     * @return
     */
    @PostMapping("/sendMsg")
    public R<String> sendMsg(@RequestBody User user, HttpServletRequest request){
        //1.通过工具类获取 长度为4位的 随机验证码 code
        String code = ValidateCodeUtils.generateValidateCode(4).toString();
        //2.取出user中的phone字段
        String phone = user.getPhone();
        try {
            // 3.通过阿里云SMS服务 为指定手机号码发送短信验证码
            //SMSUtils.sendMessage("*****", "*******", phone, code);
            log.info("为指定手机号码发送登陆短信:" + code);
            // 4.将生成的验证码code 保存到session域中
//            request.getSession().setAttribute(phone, code);
            ValueOperations ops = redisTemplate.opsForValue();
            ops.set(phone,code,5, TimeUnit.MINUTES);
            return R.success("发送短信成功");
        }catch (Exception e){
            e.printStackTrace();
            return R.error("发送短信失败");
        }
    }


    /**
     *  登陆逻辑分析:
     *       1.获取map中保存的phone和code字段
     *       2.取出session域中 保存的验证码 validateCode
     *       3. 判断validateCode是否不为空  并且validateCode与code相等
     *       4. 通过userService查询 user表中是否出现过 指定手机号码的用户对象 user
     *       5. 当user对象为空时 则创建User对象 并将手机号码 及其其他的字段赋值  通过userService调用save方法执行添加操作
     *       6. 将当前User对象的id 保存到session域中 为之后的访问放行 作准备
     * @param map
     * @param session
     * @return
     */
    @PostMapping("/login")
    public R<String> login(@RequestBody Map map, HttpSession session){
        // 1.获取map中保存的phone和code字段
        String phone = map.get("phone").toString();
        String code = map.get("code").toString();
        //2.取出session域中 保存的验证码 validateCode
//        String validateCode = session.getAttribute(phone).toString();
//        从redis中获取验证码
        String validateCode = (String) redisTemplate.opsForValue().get(phone);
        //3. 判断validateCode是否不为空  并且validateCode与code相等
        if(validateCode!=null&& validateCode.equals(code)){

             redisTemplate.delete(phone);

            // 4. 通过userService查询 user表中是否出现过 指定手机号码的用户对象 user
            QueryWrapper<User> queryWrapper =new QueryWrapper<>();
            queryWrapper.eq("phone",phone);
            User user = this.userService.getOne(queryWrapper);
            // 5. 当user对象为空时 则创建User对象 并将手机号码 及其其他的字段赋值  通过userService调用save方法执行添加操作
            if(user==null){
                //则创建User对象
                user = new User();
                user.setPhone(phone);
                //通过userService调用save方法执行添加操作
                this.userService.save(user);
            }
            //6. 将当前User对象的id 保存到session域中 为之后的访问放行 作准备
            session.setAttribute("user",user.getId());
            return R.success("登陆成功");
        }
        return R.success("登陆失败");
    }

}
